package com.hd123.rumba.gwt.widget2.client.misc;

import java.util.Stack;

import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * 半透明遮罩，常被模态对话框用于覆盖整个页面
 * <p>
 * 支持多层遮罩，例如在多个对话框重叠显示时
 * 
 * @author LiQi
 * 
 */
public class RMask extends HTMLPanel {

  public static final String STYLENAME = "rb-Mask";

  /** 多层遮罩堆栈 */
  private static Stack maskStack = new Stack();

  private RMask() {
    super("");
    setStyleName(STYLENAME);
    setWidth("100%");

    Window.addResizeHandler(new WindowHandler());
  }

  /**
   * 显示遮罩
   * 
   */
  public static void show() {
    RMask mask = new RMask();
    maskStack.push(mask);
    mask.doShow();
  }

  /**
   * 隐藏遮罩，如果存在多层遮罩，则只隐藏最上层的一个
   * 
   */
  public static void hide() {
    if (maskStack.isEmpty())
      return;

    RMask mask = (RMask) maskStack.pop();
    mask.doHide();
  }

  /**
   * 隐藏遮罩，如果存在多层遮罩，则全部隐藏
   * 
   */
  public static void hideAll() {
    while (!maskStack.isEmpty()) {
      RMask mask = (RMask) maskStack.pop();
      mask.doHide();
    }
  }

  /**
   * 显示遮罩
   * 
   */
  protected void doShow() {
    if (getParent() != null)
      return;

    setHeight(new Integer(getHeight()).toString() + "px");
    RootPanel.get().add(this, 0, 0);
  }

  /**
   * 隐藏遮罩
   * 
   */
  protected void doHide() {
    RootPanel.get().remove(this);
  }

  /**
   * 计算高度
   * 
   * @return
   */
  private static native int getHeight()
  /*-{
    return Math.max($doc.body.scrollHeight, $doc.body.clientHeight);
  }-*/;

  /**
   * 窗口事件处理，保证在窗口改变大小时遮罩能正确显示
   * 
   * @author LiQi
   * 
   */
  private class WindowHandler implements ResizeHandler {
    public void onResize(ResizeEvent event) {
      RMask.this.setHeight(new Integer(getHeight()).toString() + "px");
    }
  }
}
